#!/usr/bin/env bash
set -euo pipefail

# Dumbo_NG 4节点分布式编排脚本 (改进版)
# 功能：
# 1) 生成统一 .committee.json（使用公网IP与端口9000-9003）
# 2) 将 committee 分发至四台机器 /home/Dumbo_NG/.committee.json
# 3) 在四台机器上按 node_id 启动 Dumbo_NG（./main run），后台运行
# 4) 校验进程、端口与日志尾部，并打印摘要
# 5) 改进：完整的日志重定向、Go环境配置、进程清理

# 使用方法：
#   chmod +x benchmark/run_multi_host.sh
#   benchmark/run_multi_host.sh \
#     --password 'Aa123456' \
#     --ips 47.112.3.228,47.251.242.128,47.107.95.7,47.237.6.255 \
#     [--ports 9000,9001,9002,9003]

PASSWORD=""
IPS_CSV=""
PORTS_CSV="9000,9001,9002,9003"

while [[ $# -gt 0 ]]; do
  case "$1" in
    --password)
      PASSWORD="$2"; shift 2 ;;
    --ips)
      IPS_CSV="$2"; shift 2 ;;
    --ports)
      PORTS_CSV="$2"; shift 2 ;;
    *) echo "Unknown arg: $1" >&2; exit 1 ;;
  esac
done

if [[ -z "$PASSWORD" || -z "$IPS_CSV" ]]; then
  echo "Usage: $0 --password <PASSWORD> --ips ip0,ip1,ip2,ip3 [--ports 9000,9001,9002,9003]" >&2
  exit 2
fi

IFS=',' read -r IP0 IP1 IP2 IP3 <<<"$IPS_CSV"
IFS=',' read -r P0 P1 P2 P3 <<<"$PORTS_CSV"

command -v sshpass >/dev/null 2>&1 || {
  echo "Installing sshpass...";
  sudo apt-get update -y >/dev/null 2>&1 || true
  sudo apt-get install -y sshpass >/dev/null 2>&1 || true
}

tmp_dir="$(mktemp -d)"
trap 'rm -rf "$tmp_dir"' EXIT

# 1) 生成统一 committee
cat >"$tmp_dir/committee.json" <<EOF
{
  "0": {"name": "node0", "node_id": 0, "addr": "${IP0}:${P0}"},
  "1": {"name": "node1", "node_id": 1, "addr": "${IP1}:${P1}"},
  "2": {"name": "node2", "node_id": 2, "addr": "${IP2}:${P2}"},
  "3": {"name": "node3", "node_id": 3, "addr": "${IP3}:${P3}"}
}
EOF

ips=("$IP0" "$IP1" "$IP2" "$IP3")
ports=("$P0" "$P1" "$P2" "$P3")

remote_start_script="$tmp_dir/remote_start_dumbo.sh"
cat >"$remote_start_script" <<'RS'
#!/bin/bash
set -euo pipefail
NID="$1"
cd /home/Dumbo_NG

# 改进：设置Go环境变量
export GOROOT="/usr/local/go"
export GOPATH="/home/go"
export PATH="/usr/local/go/bin:$PATH"

# 改进：彻底清理旧进程和端口
echo "=== 清理旧进程和端口 ==="
pkill -f "main run" || true
sleep 2

# 清理端口
for port in 9000 9001 9002 9003; do
    fuser -k -n tcp $port 2>/dev/null || true
    pid=$(ss -ltnp 2>/dev/null | awk -v prt=":$port" '$0 ~ prt {print $NF}' | sed -n 's/.*pid=\([0-9]\+\).*/\1/p' | head -n1)
    [ -n "${pid:-}" ] && kill -9 "$pid" 2>/dev/null || true
done
sleep 1

# 改进：创建日志目录结构
mkdir -p logs "logs/node-${NID}"

# 改进：清理旧数据存储，避免 NutsDB bucket 冲突
rm -rf "db-${NID}"*

# 改进：使用时间戳避免bucket冲突
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
STORE_PATH="db-${NID}-${TIMESTAMP}"
mkdir -p "$STORE_PATH"

KEY=".node-key-${NID}.json"
TSK=".node-ts-key-${NID}.json"
COM=".committee.json"
PAR=".parameters.json"
LOG_DIR="logs/node-${NID}"

# 改进：启动Dumbo_NG，使用完整的日志重定向
echo "=== 启动Dumbo_NG节点 $NID ==="
nohup ./main run \
    --keys "$KEY" \
    --threshold_keys "$TSK" \
    --committee "$COM" \
    --parameters "$PAR" \
    --store "$STORE_PATH" \
    --log_out "$LOG_DIR" \
    --log_level 4 \
    --node_id "$NID" \
    > "$LOG_DIR/out.log" 2>&1 &

PID=$!
echo "Dumbo_NG节点 $NID 启动完成，PID: $PID"
echo "$PID" > "$LOG_DIR/pid.txt"

# 改进：等待启动并验证
sleep 3
echo "=== 验证启动状态 ==="
echo "[进程检查]"; pgrep -fa "/home/Dumbo_NG/main run" || true
echo "[端口检查]"; ss -ltn | egrep ":9000|:9001|:9002|:9003" || true

# 改进：检查日志文件
echo "=== 检查日志文件 ==="
tail_target="$LOG_DIR/node-info-${NID}.log"
if [[ -s "$tail_target" ]]; then
    echo "[日志] $tail_target (最后40行):"
    tail -n 40 "$tail_target"
else
    echo "[日志] $LOG_DIR/out.log (最后40行):"
    tail -n 40 "$LOG_DIR/out.log" || echo "日志文件不存在或为空"
fi
RS

chmod +x "$remote_start_script"

for i in 0 1 2 3; do
  ip="${ips[$i]}"
  echo "=== 配置与启动 node-${i} @ ${ip} ==="
  sshpass -p "$PASSWORD" scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$tmp_dir/committee.json" root@"$ip":/home/Dumbo_NG/.committee.json
  sshpass -p "$PASSWORD" scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$remote_start_script" root@"$ip":/root/remote_start_dumbo.sh
  sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@"$ip" "bash /root/remote_start_dumbo.sh ${i}"
  echo
done

echo "完成：已尝试在四台机器上启动 Dumbo_NG 节点。"


